package com.moyuduo.java8.lambda;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import org.junit.Test;

/**
*@author litao,School of computer and software engineering,Xihua University
*@date 2020年3月21日
*Lambda表达式基础语法:Java8中引入了操作符"->"称为箭头操作符或Lambda操作符
*操作符左侧:Lambda表达式的参数列表
*操作符右侧:Lambda表达式要执行的功能
*
*语法一:无参数无返回值
*	()->System.out.println("Hello,Lambda!");
*
*语法二:有参数无返回值
*	(x)->System.out.println(x);
*
*语法三:有一个参数无返回值,小括号可以省略
*	x->System.out.println(x);
*
*语法四:有两个参数并且有返回值
*	Comparator<Integer> com=(x,y)->{
*			return Integer.compare(x, y);
*		};
*		
*语法五:当只有一条return语句,那么大括号和return都可以省略
*	(x,y)->Integer.compare(x, y);
*
*语法六:Lambda表达式的参数列表类型可以不写,JVM会通过上下文推断
*	(Integer x,Integer y)->Integer.compare(x, y);
*	( x, y)->Integer.compare(x, y);
*
*Lambda表达式需要函数式接口的支持:
*	函数式接口:接口中只有一个方法
*/
public class LambdaTest {

	@Test
	public void test1() {
		Runnable r1=new Runnable() {
			public void run() {
				System.out.println("Hello,Lambda!");
			}
		};
		r1.run();
		System.out.println("-------------");
		Runnable r2=()->System.out.println("Hello,Lambda!");
		r2.run();
	}
	
	@Test
	public void test2() {
		Consumer<String> con=(x)->System.out.println(x);
		con.accept("Hello,Lambda!");
	}
	
	@Test
	public void test3() {
		Consumer<String> con=x->System.out.println(x);
		con.accept("Hello,Lambda!");
	}
	
	@Test
	public void test4() {
		Comparator<Integer> com=(x,y)->{
			return Integer.compare(x, y);
		};
	}
	
	@Test
	public void test5() {
		Comparator<Integer> com=(x,y)->Integer.compare(x, y);
	}
	
	@Test
	public void test6() {
		Comparator<Integer> com1=(Integer x,Integer y)->Integer.compare(x, y);
		Comparator<Integer> com2=( x, y)->Integer.compare(x, y);
	}
	
	//方法无参数无返回值
	@Test
	public void test7() {
		NoParamNoReturn noParamNoReturn=()->System.out.println("No param No return");
		noParamNoReturn.lambda();
	}
	
	//方法有一个或多个参数无返回值
	@Test
	public void test8() {
		OneParamNoReturn oneParamNoReturn=x->System.out.println(x);
		oneParamNoReturn.lambda(10);
	}
	
	//方法无参数有返回值
	@Test
	public void test9() {
		NoParamHasReturn noParamHasReturn=()-> 10;
		noParamHasReturn.lambda();
	}
	
	//方法有一个或多个参数有返回值
	@Test
	public void test10() {
		HasParamHasReturn hasParamHasReturn=(x,y)->x+y;
		hasParamHasReturn.lambda(10, 20);
	}
	
	public int add(int x,int y) {
		return x+y;
	}
	
	//lambda表达式引用方法
	@Test public void test11() {
		LambdaTest lt=new LambdaTest();
		HasParamHasReturn hasParamHasReturn=lt::add;
		hasParamHasReturn.lambda(10, 20);
	}
	
	public static int sub(int x,int y) {
		return x-y;
	}
	
	
	//lambda表达式引用静态方法
	@Test
	public void test12() {
		HasParamHasReturn hasParamHasReturn=LambdaTest::sub;
		hasParamHasReturn.lambda(10, 20);
	} 
	
	@Test
	public void test() {
		BiPredicate<String,String> bp=(x,y)->x.equals(y);
		//也可以简写为
		BiPredicate<String,String> bp2=String::equals;
	}
	
	//使用lambda表达式引用构造器
	@Test
	public void test13() {
		UserCreatorBlankConstruct creator1=User::new;
		creator1.getUser();
		
		UserCreatorParamConstruct creator2=User::new;
		creator2.getUser("tom", 20);
	}
	
	//使用lambda表达式遍历List
	@Test
	public void test14() {
		List<Integer> list=new ArrayList<>();
		list.add(1);
		list.add(3);
		list.add(5);
		list.add(7);
		list.forEach(System.out::println);
	}
	
	//java8内置 供给型函数接口Supplier
	@Test
	public void test15() {
		Supplier<User> supplier=User::new;
		User user = supplier.get();
	}
	
	
	//java8内置 函数型函数接口Function
	@Test
	public void test16() {
		Function<String, String> fun=s->{s=s.trim();s=s.toUpperCase();return s;};
		String apply = fun.apply(" abCd");
	}
	
	//删除List元素
	@Test
	public void test17() {
		List<User> list=new ArrayList<>();
		list.add(new User("tom",20));
		list.add(new User("jack",18));
		list.add(new User("marry",22));
		
		list.removeIf(e->e.getName()=="jack");
	}
	
	@Test
	public void test18() {
		Supplier< String> supplier =MTest.u::getName;
		String name = supplier.get();
		System.out.println(name);
	}
	
	//使用内置函数式接口创建对象
	@Test
	public void test19() {
		Supplier<User> supplier=User::new;
		User user = supplier.get();
		System.out.println(user);
	}
	
	//使用内置函数式接口创建对象
	@Test
	public void test20() {
		BiFunction<String,Integer,User> biFunction=User::new;
		User user = biFunction.apply("tom", 20);
		System.out.println(user);
	}
}

class User{
	String name;
	int age;
	
	public User() {}
	
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
	
	
}